package com.nrrg.jgraphtTest;

import org.jgrapht.Graph;
import org.jgrapht.alg.scoring.BetweennessCentrality;
import org.jgrapht.generate.GnpRandomGraphGenerator;
import org.jgrapht.graph.DefaultEdge;
import org.jgrapht.graph.SimpleGraph;
import org.jgrapht.util.SupplierUtil;

import java.util.*;
import java.util.function.Supplier;

public class gTest2 {
    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();

        Supplier<Integer> vSup = new Supplier<>(){
            private int id = 0;

            @Override
            public Integer get() { return id++;}
        };

        Graph<Integer, DefaultEdge> erGraph = new SimpleGraph<>(vSup, SupplierUtil.createDefaultEdgeSupplier(),false);
        GnpRandomGraphGenerator<Integer, DefaultEdge> erGraphGen = new GnpRandomGraphGenerator<>(100,0.7);
        erGraphGen.generateGraph(erGraph);

        BetweennessCentrality<Integer, DefaultEdge> erGraphBetweenness = new BetweennessCentrality<>(erGraph);
        Map<Integer, Double> erGraphBetweenessMap = erGraphBetweenness.getScores();
        Map<Integer, Double> capacityMap = new HashMap<>();
        Map<Integer, Double> trafficMap = new HashMap<>(erGraphBetweenessMap);
        trafficMap.forEach( (k , v) -> capacityMap.put(k , (1 + 0.1) * v));

        Set<Integer> vertexSet = erGraph.vertexSet();
        List<Integer> vertexList = new ArrayList<>(vertexSet);
        HashSet<Integer> initalAttackVertexs = new HashSet<>();
        float initalAttackProbability = (float) 0.6;
        int initalAttackNumber = (int) (vertexSet.size() * initalAttackProbability);
        for (int i = 0; i < initalAttackNumber; i++) {
            int temp = (int) (Math.random() * initalAttackNumber);
            initalAttackVertexs.addAll(Collections.singleton(vertexList.get(temp)));
            vertexList.set(temp, vertexList.get(initalAttackNumber));
            initalAttackNumber--;
        }
        
        for (int k = 1; k <= 100; k++) {
            Graph<Integer, DefaultEdge> g = new SimpleGraph<>(vSup, SupplierUtil.createDefaultEdgeSupplier(),false);
            erGraph.vertexSet().forEach(v -> g.addVertex(v));
//            Set<DefaultEdge> a = erGraph.edgeSet();
            erGraph.edgeSet().forEach(e -> g.addEdge(g.getEdgeTarget(e), g.getEdgeSource(e)));
//            for (DefaultEdge e:erGraph.edgeSet()){
////                System.out.printf(String.valueOf(e));
//                g.addEdge(e.getSource(), e);
//            }
            Set<Integer> failVertexs = new HashSet<>(initalAttackVertexs);
            
            int i = 1;
            while (!failVertexs.isEmpty()) {
                g.removeAllVertices(failVertexs);
                BetweennessCentrality<Integer, DefaultEdge> erGraphBetweennessEachTime = new BetweennessCentrality<>(erGraph);
                trafficMap = erGraphBetweennessEachTime.getScores();
                failVertexs.clear();
                for (Integer j : trafficMap.keySet()) {
                    if (trafficMap.get(j) > capacityMap.get(j)) {
                        failVertexs.add(j);
                    }
                }
                System.out.println("The giant component graph size is: " + g.vertexSet().size() + " in " + i + " step.");
                i++;
            }
        }


        long endTime = System.currentTimeMillis();
        System.out.println((float)(endTime - startTime)/1000);
    }
}
